import { Injectable } from "@angular/core";
import { ConnectionBackend, RequestOptions, Request, RequestOptionsArgs, Response, Http, Headers } from "@angular/http";
import { Observable } from "rxjs/Rx";

import { MatSnackBar } from '@angular/material';
import { Router } from "@angular/router";

@Injectable()
export class InterceptedHttp extends Http {

  constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, private matSnackBar: MatSnackBar,private router:Router) {

    super(backend, defaultOptions);

  }

  request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
    return super.request(url, options);
  }

  get(url: string, options?: RequestOptionsArgs): Observable<Response> {
    if (options == null) {
      options = new RequestOptions();
    }
    if (options.headers == null) {
      options.headers = new Headers();
    }

    // jwt header
    let token: string = localStorage.getItem('token');

    // console.error("token:"+token);
    if (token) {
      options.headers.append('token', token);
    }

    return this.intercept(super.get(url, this.getRequestOptionArgs(options)));
  }

  post(url: string, body: any, options): Observable<Response> {

    //form data encodeURIComponent
    let str = [];
    for (let p in body) {
      str.push(encodeURIComponent(p) + "=" + encodeURIComponent(body[p]));
    }
    body = str.join("&");

    console.log(body);

    if (options == null) {
      options = new RequestOptions();
    }
    if (options.headers == null) {
      options.headers = new Headers();
    }
    options.headers.append('Content-Type', 'application/x-www-form-urlencoded');

    // jwt header
    let token: string = localStorage.getItem('token');

    // console.error("token:"+token);
    if (token) {
      options.headers.append('token', token);
    }
    return this.intercept(super.post(url, body, options));
  }

  put(url: string, body: string, options?: RequestOptionsArgs): Observable<Response> {

    return super.put(url, body, this.getRequestOptionArgs(options));
  }

  delete(url: string, options?: RequestOptionsArgs): Observable<Response> {

    return super.delete(url, this.getRequestOptionArgs(options));
  }


  // 添加header
  private getRequestOptionArgs(options?: RequestOptionsArgs): RequestOptionsArgs {
    if (options == null) {
      options = new RequestOptions();
    }
    if (options.headers == null) {
      options.headers = new Headers();
    }
    options.headers.append('Content-Type', 'application/json')

    return options;
  }

  // reponse 拦截
  intercept(observable: Observable<Response>): Observable<Response> {

    return observable.map((res) => {

      // console.log(res);

      let token: string = res.headers.get('token');

      if (token && token != localStorage.getItem('token')) {
        localStorage.setItem('token', token);
      }


      // console.log(url);
      // let url:string = res.url;


      let data = res.json();

      if (data.success) {

        // 成功有返回提示信息
        if (data['success_messege']) {
          this.matSnackBar.open(data['success_massege'], '', {
            duration: 2000,
            panelClass:'success',
            verticalPosition: 'top',
            horizontalPosition: 'right'
          });
        }

        return data;        

      } else {

        // 用户过期
        if (data['token_message']) {

          console.log('----------token bad------------');
          // 销毁用户
          localStorage.removeItem('token');

          this.router.navigate(['/login']);

        }

        // 错误提示
        if (data['error_messege']) {
          this.matSnackBar.open(data['error_messege'], '', {
            duration: 2000,
            panelClass:'error',
            verticalPosition: 'top',
            horizontalPosition: 'right'
          });
        }

        // 警告提示
        if (data['info_messege']) {
          this.matSnackBar.open(data['info_messege'], '', {
            duration: 2000,
            panelClass:'info',
            verticalPosition: 'top',
            horizontalPosition: 'right'
          });
        }

        throw Observable.throw(data).error;

      }

    }).catch((err: any) => {
      console.log(err);
      console.log("Caught error: " + err);

      throw Observable.throw(err).error;

    });



  }


}
